// app.js// app.js
import Notify from '@vant/weapp/notify/notify';
import dayjs from 'dayjs';
import { userTypeEnum, userStatEnum } from './pages/common/enums';
App({
  // App初始化
  onLaunch: function () {
    if (!wx.cloud) {
      console.error('请使用 2.2.3 或以上的基础库以使用云能力');
    } else {
      wx.cloud.init({
        env: "prod-2g9ap8f37370cbae",
        traceUser: true,
      });
      // 导航栏属性
      wx.getSystemInfo({
        success: e => {
          this.globalData.StatusBar = e.statusBarHeight;
          let capsule = wx.getMenuButtonBoundingClientRect();
          if (capsule) {
            this.globalData.Custom = capsule;
            this.globalData.CustomBar = capsule.bottom + capsule.top - e.statusBarHeight;
          } else {
            this.globalData.CustomBar = e.statusBarHeight + 50;
          }
        }
      })
      // 版本更新
      this.updateManager();
      // 清理缓存文件
      this.clearTmpFile(7);
      // 从缓存中获取openId，如果不存在则调用登录接口
      const openId = wx.getStorageSync('openId');
      if (!openId) {
        this.login();
      } else {
        this.loadUserInfo();
      }
    }
  },
  /**
   * 小程序主动更新
   */
  updateManager() {
    if (!wx.canIUse('getUpdateManager')) {
      return false;
    }
    const updateManager = wx.getUpdateManager();
    updateManager.onCheckForUpdate(function (res) {});
    updateManager.onUpdateReady(function () {
      wx.showModal({
        title: '有新版本',
        content: '新版本已经准备好，即将重启',
        showCancel: false,
        success(res) {
          if (res.confirm) {
            updateManager.applyUpdate()
          }
        }
      });
    });
    updateManager.onUpdateFailed(function () {
      wx.showModal({
        title: '更新提示',
        content: '新版本下载失败',
        showCancel: false
      })
    });
  },
  // 用户登录
  login() {
    wx.login({
      success: (res) => {
        if (res.code) {
          const param = {
            code: res.code
          }
          this.callContainer('/wx/login', param, (res) => {
            console.log('登录成功！获取到用户唯一标识！');
            this.globalData.openId = res.data.data.openid;
            wx.setStorageSync('openId', res.data.data.openid);
            // 加载用户信息
            this.loadUserInfo();
          }, (res) => {
            console.log('登录失败！', res);
          });
        } else {
          console.log('登录失败！' + res.errMsg)
        }
      }
    })
  },
  // 加载用户信息
  loadUserInfo() {
    // 通过openId查询用户信息
    const openId = wx.getStorageSync('openId');
    this.globalData.openId = openId;
    const param = {
      wxOpenId: openId
    }
    this.callContainer('/api/user/query', param, (res) => {
      if (res.data.data.userId) {
        // 用户信息已存在
        res.data.data.userType_label = userTypeEnum.get(res.data.data.type);
        res.data.data.userStat_label = userStatEnum.get(res.data.data.status);
        this.globalData.userInfo = res.data.data;
        if (this.checkLoginReadyCallback) {
          this.checkLoginReadyCallback();
        }
      } else {
        // 用户信息不存在
        const addParam = {
          ...this.globalData.userInfo,
          wxOpenId: openId
        }
        this.callContainer('/api/user/add', addParam, (res) => {
          if (res.data.data.userId) {
            res.data.data.userType_label = userTypeEnum.get(1);
            res.data.data.userStat_label = userStatEnum.get(1);
            this.globalData.userInfo = res.data.data;
            if (this.checkLoginReadyCallback) {
              this.checkLoginReadyCallback();
            }
          }
        });
      }
    });
  },
  // 云托管接口调用
  callContainer(url, param, succCallBackFunc, failCallBackFunc) {
    wx.cloud.callContainer({
      "config": {
        "env": "prod-2g9ap8f37370cbae"
      },
      "path": url,
      "header": {
        "X-WX-SERVICE": "springboot-gp9w",
        "content-type": "application/json"
      },
      "method": "POST",
      "data": {
        ...param,
        userId: this.globalData.userInfo.userId,
      },
      "success": (res) => {
        if (res.statusCode == 200 && res.data && res.data.code == 0) {
          succCallBackFunc(res);
        } else {
          if (res.data.message) {
            Notify({ type: 'warning', message: res.data.message, top: this.globalData.CustomBar });
          } else {
            Notify({ type: 'danger', message: '操作失败（' + res.data.error + '）', top: this.globalData.CustomBar });
          }
          if (failCallBackFunc) {
            failCallBackFunc(res);
          } else {
            console.log('url=' + url + '调用服务失败：', res);
          }
        }
      },
      "fail": (res) => {
        Notify({ type: 'danger', message: '操作失败', top: this.globalData.CustomBar });
        if (failCallBackFunc) {
          failCallBackFunc(res);
        } else {
          console.log('url=' + url + '调用服务失败：', res);
        }
      },
    })
  },
  // websocket连接
  connectWsMsg(onMsgCallBack) {
    wx.getLocalIPAddress({
      success: async (res) => {
        const localip = res.localip;
        const connectWsMsg = this.connectWsMsg;
        const { socketTask } = await wx.cloud.connectContainer({
          config: {
            env: 'prod-2g9ap8f37370cbae',
          },
          service: 'springboot-gp9w',
          path: '/ws/picture/' + localip + '-' + this.globalData.userInfo.userId,
        })
        this.socketTask = socketTask;
        socketTask.onMessage((res) => {
          console.log('【WEBSOCKET】收到消息：', res.data)
          if (res.data != "连接成功") {
            onMsgCallBack(JSON.parse(res.data));
          }
        })
        socketTask.onOpen((res) => {
          console.log('【WEBSOCKET】连接成功！')
        })
        socketTask.onClose((res) => {
          if (!this.disConnectWsMsgFlag) {
            // 重新连接
            console.log('【WEBSOCKET】连接断开，尝试重新连接！')
            setTimeout(() => {
              connectWsMsg(onMsgCallBack);
            }, 1000)
          } else {
            this.disConnectWsMsgFlag = false;
          }
        })
        // 开启心跳定时器
        this.startWsTimer(socketTask, onMsgCallBack);
      },
    })
  },
  // websocket消息心跳定时器
  startWsTimer(socketTask, onMsgCallBack) {
    clearInterval(this._timer);
    this._timer = setInterval(() => {
      socketTask.send({
        data: '心跳包',
        fail: (res) => {
          console.log('websocket心跳失败，重新连接：', res);
          // 重接websocket消息
          this.connectWsMsg(onMsgCallBack);
        }
      })
    }, 30000);
  },
  // websocket断开
  disConnectWsMsg() {
    this.disConnectWsMsgFlag = true;
    clearInterval(this._timer);
    this.socketTask.close({
      success: (res) => {
        console.log('【WEBSOCKET】连接关闭！', res);
      },
      fail: (res) => {
        console.log('【WEBSOCKET】连接关闭失败！', res);
      }
    });
  },
  // 文件上传
  uploadFilePromise(cloudPath, filePath) {
    return wx.cloud.uploadFile({
      "cloudPath": cloudPath,
      "filePath": filePath,
      "config": {
        "env": 'prod-2g9ap8f37370cbae'
      },
    });
  },
  // 获取缓存文件路径（文件url）
  getTempFilePath(url) {
    let that = this;
    return new Promise((resolve, reject) => {
      let imageCacheMapStr = wx.getStorageSync('image_cache');
      let imageCacheMap = new Map();
      if (imageCacheMapStr) {
        imageCacheMap = new Map(JSON.parse(imageCacheMapStr));
      }
      if (imageCacheMap.has(url)) {
        const pathInfo = imageCacheMap.get(url);
        resolve(pathInfo.tmpUrl);
      } else {
        wx.cloud.downloadFile({
          fileID: url,
          success: function (res) {
            if (res.statusCode === 200) {
              const fs = wx.getFileSystemManager();
              fs.saveFile({
                tempFilePath: res.tempFilePath, // 传入一个临时文件路径
                success(res) {
                  const tmpPathInfo = {
                    tmpUrl: res.savedFilePath,
                    initDate: dayjs().format('YYYYMMDD'),
                  }
                  let imageCacheMapNewStr = wx.getStorageSync('image_cache');
                  let imageCacheMapNew = new Map(JSON.parse(imageCacheMapNewStr));
                  imageCacheMapNew.set(url, tmpPathInfo);
                  wx.setStorageSync('image_cache', JSON.stringify([...imageCacheMapNew]));
                  resolve(res.savedFilePath);
                },
                fail(res1) {
                  console.log('saveFile fail:', res1);
                  console.log('开始清理缓存文件...');
                  // 清理缓存文件
                  that.clearTmpFile(1);
                  fs.saveFile({
                    tempFilePath: res.tempFilePath, // 传入一个临时文件路径
                    success(res) {
                      const tmpPathInfo = {
                        tmpUrl: res.savedFilePath,
                        initDate: dayjs().format('YYYYMMDD'),
                      }
                      let imageCacheMapNewStr = wx.getStorageSync('image_cache');
                      let imageCacheMapNew = new Map(JSON.parse(imageCacheMapNewStr));
                      imageCacheMapNew.set(url, tmpPathInfo);
                      wx.setStorageSync('image_cache', JSON.stringify([...imageCacheMapNew]));
                      console.log('清理后 保存成功:', res.savedFilePath);
                      resolve(res.savedFilePath);
                    },
                    fail() {
                      console.log('清理后 saveFile fail:', res1);
                      resolve(url);
                    }
                  })
                },
              });
            }
          },
          fail: function (res) {
            console.log('downloadFile fail:', res);
            resolve(url);
          }
        });
      }
    })
  },
  // 批量获取换成文件路径（文件url列表）
  getBtchTempFilePath(urlList) {
    return new Promise((resolve, reject) => {
      let tmpUrlList = [];
      for (let index = 0; index < urlList.length; index++) {
        const url = urlList[index];
        this.getTempFilePath(url).then((res) => {
          tmpUrlList.push(res);
          if (index == urlList.length - 1) {
            resolve(tmpUrlList);
          }
        })
      }
    });
  },
  // 批量获取换成文件路径（文件对象列表）
  getBtchTempFilePathByObj(urlObjList, objField) {
    return new Promise((resolve, reject) => {
      let tmpUrlList = [];
      for (let index = 0; index < urlObjList.length; index++) {
        const urlObj = urlObjList[index];
        const url = urlObj?.url;
        if (objField) {
          url = urlObj?.objField;
        }
        this.getTempFilePath(url).then((res) => {
          tmpUrlList.push(res);
          if (index == urlObjList.length - 1) {
            resolve(tmpUrlList);
          }
        })
      }
    });
  },
  // 批量获取换成文件路径（同步）（文件对象列表）
  async getBtchTempFilePathByObjSync(urlObjList, objField) {
    let data;
    await this.getBtchTempFilePathByObj(urlObjList, objField).then((res) => {
      data = res;
    });
    return data;
  },
  // 清理超过一个星期的缓存文件
  clearTmpFile(dayCount) {
    const fs = wx.getFileSystemManager();
    const storage = wx.getStorageInfoSync()
    let imageCacheMapStr = wx.getStorageSync('image_cache');
    let imageCacheMap = new Map();
    if (imageCacheMapStr) {
      imageCacheMap = new Map(JSON.parse(imageCacheMapStr));
    }
    const today = dayjs().format('YYYYMMDD');
    for (const key of imageCacheMap.keys()) {
      const value = imageCacheMap.get(key);
      // 一周
      const initDate = dayjs(value.initDate + '').add(dayCount, 'day').format('YYYYMMDD');
      if (initDate < today) {
        imageCacheMap.delete(key);
        fs.removeSavedFile({
          filePath: value.tmpUrl, // 传入一个临时文件路径
        });
      }
    }
    wx.setStorageSync('image_cache', JSON.stringify([...imageCacheMap]));
    // 删除超过一周的本地缓存文件（防止Storage被清理，缓存文件未清理）
    fs.getSavedFileList({
      success(res) {
        for (const file of res.fileList) {
          const createTime = dayjs(file.createTime * 1000).format('YYYYMMDD');
          const createTimeTmp = dayjs(createTime + '').add(1, 'week').format('YYYYMMDD');
          if (createTimeTmp < today) {
            fs.removeSavedFile({
              filePath: file.filePath
            });
          }
        }
      }
    })
  },
  _timer: null,
  disConnectWsMsgFlag: false,
  socketTask: null,
  checkLoginReadyCallback: null,
  globalData: {
    openId: null,
    userInfo: {
      name: '默认用户',
      avatar: 'cloud://prod-1g7xzqtyc7879346.7072-prod-1g7xzqtyc7879346-1325290517/default/默认头像.png',
      phone: '',
    },
  },
});
